import json
import time

import cv2
import requests

from logger import log
from settings import settings
from yolov5 import inference, draw_polygon_points, draw, check_inside


def post_img(frame, stream_id):
    # 将图像编码为JPEG格式
    _, buffer = cv2.imencode('.jpg', frame)
    # 转换为字节
    jpg_as_text = buffer.tobytes()
    try:
        # 创建表单数据
        files = {'contractFile': ('img.jpg', jpg_as_text)}
        # 设置请求的URL
        url = 'http://' + settings.host + '/api/account/oss/oss2'
        # 发送POST请求
        response = requests.post(url, files=files, verify=False, timeout=10)
        response.raise_for_status()  # 如果请求返回了错误状态码，这会抛出异常
        # 处理响应
        log.info(f"图片上传数据返回:{response.json()}")
        snapshotUrl = response.json()['data']
        params = {
            "id": stream_id,
            "snapshotUrl": snapshotUrl,
            "platformId": settings.platformId,
            "platformName": settings.platformName,
            "type": "invade"
        }
        requests_post = requests.post('http://' + settings.host + '/api/weigh/internal/vs_stream/snapshot',
                                      json=params)
        requests_post.raise_for_status()  # 如果请求返回了错误状态码，这会抛出异常
        log.info(f"物体检测在区域内，上传完成:{params}:{requests_post.json()}")
    except requests.RequestException as error:
        # 打印错误信息
        log.info("uploadOss2 error:", error)
    # cv2.imwrite(f'capture/capture_{timestamp}.jpg', save_image)


def screenshot(rtsp_url):
    cap = None
    try:
        cap = cv2.VideoCapture(rtsp_url)
        if cap.isOpened():
            # 寻找关键帧
            for i in range(25):
                cap.read()
            ret, frame = cap.read()
            if ret:
                return frame
            else:
                log.warn(f"ret: {ret}")
                return None
        else:
            log.warn(f"cap.isOpened() False")
            return None
    except Exception as e:
        log.error(f"e:{e}")
    finally:
        # 释放资源
        cap.release()


def main():
    while True:
        try:
            # 获取所有摄像头
            for item in settings.streams:
                # 如果找到匹配的id，获取对应的rtsp
                rtsp_url = item['rtsp']
                # rtsp_url = "sample_720p.mp4"
                polygon_points_str = item['polygonPoints']
                if polygon_points_str != '' and polygon_points_str != '[]':
                    log.info(f"{item['id']}|{item['name']}|{rtsp_url}")
                    polygon_points = json.loads(polygon_points_str)
                    frame = screenshot(rtsp_url)
                    if frame is not None:
                        # 使用YOLO处理帧
                        img, boxes, classes, scores = inference(frame)
                        # 绘制检测框
                        draw_polygon_points(img, polygon_points)
                        if boxes is not None:
                            log.info("检测到物体")
                            draw(img, boxes, scores, classes)
                            if check_inside(boxes, scores, polygon_points):
                                log.info("发现有异常，开始上传图片")
                                post_img(img, item['id'])
                        else:
                            log.info("未检测到物体")
                        # show output
                        cv2.imshow("post process result", img)
                        cv2.waitKey(1)
                        time.sleep(1)
            # time.sleep(1)
        except Exception as e:
            log.error(f"程序已中断{e}")
        finally:
            cv2.destroyAllWindows()
        time.sleep(1)
